#include "include.h"

_MB_DEVCOMIN_T MB_DevComIn;


void MeBsp_DevComIn_DMA_Init(void)
{
  dma_init_type dma_init_struct;
  
  /* enable dma2 periph clock */
  crm_periph_clock_enable(CRM_DMA2_PERIPH_CLOCK, TRUE);
  
  dma_reset(DMA2_CHANNEL2);
  dma_default_para_init(&dma_init_struct);
  dma_init_struct.direction = DMA_DIR_PERIPHERAL_TO_MEMORY;
  dma_init_struct.memory_data_width = DMA_MEMORY_DATA_WIDTH_BYTE;
  dma_init_struct.memory_inc_enable = TRUE;
  dma_init_struct.peripheral_data_width = DMA_PERIPHERAL_DATA_WIDTH_BYTE;
  dma_init_struct.peripheral_inc_enable = FALSE;
  dma_init_struct.priority = DMA_PRIORITY_HIGH;
  dma_init_struct.loop_mode_enable = FALSE;
  dma_init(DMA2_CHANNEL2, &dma_init_struct);

  dma_interrupt_enable(DMA2_CHANNEL2,DMA_FDT_INT,TRUE);
  /* flexible function enable */
  dma_flexible_config(DMA2, FLEX_CHANNEL2, DMA_FLEXIBLE_UART1_RX);
  
  dma_reset(DMA2_CHANNEL3);
  dma_default_para_init(&dma_init_struct);
  dma_init_struct.direction = DMA_DIR_MEMORY_TO_PERIPHERAL;
  dma_init_struct.memory_data_width = DMA_MEMORY_DATA_WIDTH_BYTE;
  dma_init_struct.memory_inc_enable = TRUE;
  dma_init_struct.peripheral_data_width = DMA_PERIPHERAL_DATA_WIDTH_BYTE;
  dma_init_struct.peripheral_inc_enable = FALSE;
  dma_init_struct.priority = DMA_PRIORITY_HIGH;
  dma_init_struct.loop_mode_enable = TRUE;
  dma_init(DMA2_CHANNEL3, &dma_init_struct);
  dma_interrupt_enable(DMA2_CHANNEL3,DMA_FDT_INT,TRUE);
  /* flexible function enable */
  dma_flexible_config(DMA2, FLEX_CHANNEL3, DMA_FLEXIBLE_UART1_TX);
  
  // DMA2_CHANNEL2->dtcnt = 100;
  DMA2_CHANNEL2->paddr = (uint32_t)&USART1->dt;
  // DMA2_CHANNEL2->maddr = (uint32_t)&MB_DevComIn_Data.buffer[0];
  
  // DMA2_CHANNEL3->dtcnt = 100;
  DMA2_CHANNEL3->paddr = (uint32_t)&USART1->dt;
  // DMA2_CHANNEL3->maddr = (uint32_t)MB_DevComIn.cTxBuff;
  
  dma_channel_enable(DMA2_CHANNEL2, FALSE);
  dma_channel_enable(DMA2_CHANNEL3, FALSE);
}

void MeBsp_DevComIn_Init(void)
{
  gpio_init_type gpio_init_struct;
  
  /* enable usart1 periph clock */
  crm_periph_clock_enable(CRM_USART1_PERIPH_CLOCK, TRUE);
  /* enable gpioa periph clock */
  crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
  
  nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);

  nvic_irq_enable(USART1_IRQn, 0, 0);
  nvic_irq_enable(DMA2_Channel2_IRQn, 0, 0);
  nvic_irq_enable(DMA2_Channel3_IRQn, 0, 0);
  
  MeBsp_DevComIn_DMA_Init();
  
  gpio_default_para_init(&gpio_init_struct);

  /* configure the TX pin */
  gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE;
  gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
  gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
  gpio_init_struct.gpio_pins = GPIO_PINS_9;
  gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
  gpio_init(GPIOA, &gpio_init_struct);

  /* configure the RX pin */
  gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE;
  gpio_init_struct.gpio_out_type  = GPIO_OUTPUT_PUSH_PULL;
  gpio_init_struct.gpio_mode = GPIO_MODE_INPUT;
  gpio_init_struct.gpio_pins = GPIO_PINS_10;
  gpio_init_struct.gpio_pull = GPIO_PULL_UP;
  gpio_init(GPIOA, &gpio_init_struct);

  /* configure param */
  usart_init(USART1, 250000, USART_DATA_8BITS, USART_STOP_2_BIT);
  usart_transmitter_enable(USART1, TRUE);
  usart_receiver_enable(USART1, TRUE);
  usart_parity_selection_config(USART1, USART_PARITY_NONE);

  usart_dma_transmitter_enable(USART1, TRUE);

  usart_dma_receiver_enable(USART1, TRUE);

  usart_hardware_flow_control_set(USART1, USART_HARDWARE_FLOW_NONE);

  usart_enable(USART1, TRUE);
  
  usart_interrupt_enable(USART1,USART_RDBF_INT,TRUE); //使能接收中断
  // USART1->ctrl1_bit.idleien = TRUE;
  
  memset(&MB_DevComIn, 0, sizeof(_MB_DEVCOMIN_T));
  memset(&MB_DevComIn_Data, 0, sizeof(MB_DevComIn_Data));
  memset(&MB_DevComInRep_Data, 0, sizeof(MB_DevComInRep_Data));

  USER_Debug_Out("--DevComIn Init\r\n");
}

void MeBsp_DevComIn_Hanl(void)
{
  if ( MB_DevComIn.bRecvOKFlag ) {
    MB_DevComIn.bRecvOKFlag = 0;
    MB_DevComIn.wRecvErrOutTimeCnt = 20;
    MB_DevComIn.bRecvIsConnFlag = 1;
  }
  else {
    if ( MB_DevComIn.wRecvErrOutTimeCnt ) {
      MB_DevComIn.wRecvErrOutTimeCnt--;
    }
    else {
      MB_DevComIn.bRecvIsConnFlag = 0;
    }
  }
  
}


void MeBsp_DevCom_In_DMATransmitStart(void)
{
  DMA2_CHANNEL3->ctrl_bit.chen = FALSE;
  DMA2_CHANNEL3->maddr = (uint32_t )MB_DevComIn.pTransmitBuff;
  DMA2_CHANNEL3->dtcnt = MB_DevComIn.wTransmitLength;
  DMA2_CHANNEL3->ctrl_bit.chen = TRUE;
}

void MeBsp_DevCom_In_DMAReciveStart(void)
{
  
  dma_flag_clear(DMA2_FDT2_FLAG); 
  usart_interrupt_enable(USART1,USART_RDBF_INT,FALSE); //关闭接收中断
  usart_interrupt_enable(USART1,USART_IDLE_INT,TRUE); //开启空闲中断
  DMA2_CHANNEL2->ctrl_bit.chen = FALSE;
  DMA2_CHANNEL2->maddr = (uint32_t )&MB_DevComIn_Data.buffer[0];
  DMA2_CHANNEL2->dtcnt = sizeof(MB_DevComIn_Data);
  USART1->ctrl3_bit.dmaren = TRUE;
  DMA2_CHANNEL2->ctrl_bit.chen = TRUE;
  MB_DevComIn.bRecvOKFlag = 1;
}

void MeBsp_DevCom_In_DMAReciveStop(void)
{
  MB_DevComIn.wRecvLengthVal = sizeof(MB_DevComIn_Data) - DMA2_CHANNEL2->dtcnt;
  DMA2_CHANNEL3->ctrl_bit.chen = FALSE;
  dma_flag_clear(DMA2_FDT2_FLAG);
  USART1->ctrl3_bit.dmaren = FALSE;
  usart_interrupt_enable(USART1,USART_RDBF_INT,TRUE); //开启接收中断
  usart_interrupt_enable(USART1,USART_IDLE_INT,FALSE); //关闭空闲中断

  MB_DevComIn.cRecvLineState = MB_DEVCOM_IN_LINE_RECV_IDLE;
}

void MeBsp_DevCom_In_TransmitBuff(uint8_t *p, uint16_t length)
{
  MB_DevComIn.cTransmitlineState = MB_DEVCOM_IN_LINE_SEND_START;
  MB_DevComIn.wTransmitLength = length;
  MB_DevComIn.pTransmitBuff = p;
  MB_DevComIn.wTransmitCount = 0;
  usart_flag_clear(USART1,USART_TDC_FLAG);//
  usart_interrupt_enable(USART1,USART_TDC_INT,TRUE); //使能发送中断
  USART1->dt = 0xAA;
}

void MeBsp_DevCom_In_Send(void)
{
  uint16_t length;
  if ( (MB_DevComIn.cTransmitlineState == MB_DEVCOM_IN_LINE_SEND_IDLE) && (!MB_DevComIn.wTransmitDelayCnt) ) {
    
    MB_DevComIn.wTransmitErrTimeCnt = 0;
    if ( MB_DevComOut.bRecvIsConnFlag ) {
      if ( MB_DevComOutRep_Data.packet.cLedNumVal < MB_LED_DEV_MAX_PIXEL_NUM ) {
        length = MB_DevComOutRep_Data.packet.cLedNumVal * 12+2;
        memcpy(&MB_DevComInRep_Data, &MB_DevComOutRep_Data, length);
        MB_DevComInRep_Data.packet.cLedNumVal += 1;
        length = MB_DevComOutRep_Data.packet.cLedNumVal * 12;

        MB_DevComInRep_Data.packet.wParVal[length] = MB_IBus.wCurrVal;
        MB_DevComInRep_Data.packet.wParVal[length+1] = 0;

        length = MB_DevComInRep_Data.packet.cLedNumVal * 12+2;
      }
      else {
        length = MB_DevComOutRep_Data.packet.cLedNumVal * 12+2;
        memcpy(&MB_DevComInRep_Data, &MB_DevComOutRep_Data, length);
      }
      
    }
    else {
      MB_DevComInRep_Data.packet.cLedNumVal = 1;
      length = MB_DevComInRep_Data.packet.cLedNumVal * 12+2;
      MB_DevComInRep_Data.packet.wParVal[0] = MB_IBus.wCurrVal;
      MB_DevComInRep_Data.packet.wParVal[1] = 0;
    }

    MeBsp_DevCom_In_TransmitBuff((uint8_t *)&MB_DevComInRep_Data,length);
  }
  else {
    if ( MB_DevComIn.wTransmitErrTimeCnt < 200 ) { //100us*num
      MB_DevComIn.wTransmitErrTimeCnt++;
    }
    else {
      MB_DevComIn.cTransmitlineState = MB_DEVCOM_IN_LINE_SEND_IDLE;
      MB_DevComIn.wTransmitErrTimeCnt = 0;
    }
  }
  if ( MB_DevComIn.wTransmitDelayCnt ) {
    MB_DevComIn.wTransmitDelayCnt--;
  }
}

void DMA2_Channel2_IRQHandler(void)
{
  if(dma_interrupt_flag_get(DMA2_FDT2_FLAG) != RESET) {

    MeBsp_DevCom_In_DMAReciveStop();
    DMA2_CHANNEL2->ctrl_bit.chen = FALSE;
    dma_flag_clear(DMA2_FDT2_FLAG);
  }
}


void DMA2_Channel3_IRQHandler(void)
{
  if(dma_interrupt_flag_get(DMA2_FDT3_FLAG) != RESET) {
    
    MB_DevComIn.wTransmitCount = MB_DevComIn.wTransmitLength;
		//此时DMA还没发送完数据,所以打开发送完成中断继续发数据
    usart_interrupt_enable(USART1,USART_TDC_INT,TRUE); //使能发送中断
    DMA2_CHANNEL3->ctrl_bit.chen = FALSE;
    dma_flag_clear(DMA2_FDT3_FLAG);
  }
}

void USART1_IRQHandler(void)
{
  uint8_t rev_buff;
  if((USART1->ctrl1_bit.rdbfien == SET ) && (USART1->sts & USART_RDBF_FLAG)) {
    rev_buff = USART1->dt;
    if ( (rev_buff == 0xAA) && ( MB_DevComIn.cRecvLineState == MB_DEVCOM_IN_LINE_RECV_IDLE ) ) {
      MB_DevComIn.cRecvLineState = MB_DEVCOM_IN_LINE_RECV_NORMAL;
      MeBsp_DevCom_In_DMAReciveStart();
    }
  }

  if((USART1->ctrl1_bit.idleien == SET ) && (USART1->sts & USART_IDLEF_FLAG)) {
    usart_flag_clear(USART1,USART_IDLEF_FLAG);//
    rev_buff = USART1->dt;
    MeBsp_DevCom_In_DMAReciveStop();
  }
  
  if((USART1->ctrl1_bit.tdcien == SET ) && (USART1->sts & USART_TDC_FLAG)) {
    usart_flag_clear(USART1,USART_TDC_FLAG);//
    if ( MB_DevComIn.wTransmitCount == 0 ) {
      usart_interrupt_enable(USART1,USART_TDC_INT,FALSE); //关闭发送中断
      MB_DevComIn.wTransmitCount = MB_DevComIn.wTransmitLength;
      MeBsp_DevCom_In_DMATransmitStart();
    }
    else {
      usart_interrupt_enable(USART1,USART_TDC_INT,FALSE); //使能发送中断
      MB_DevComIn.cTransmitlineState = MB_DEVCOM_IN_LINE_SEND_IDLE; //发送完成
      MB_DevComIn.wTransmitDelayCnt = 1;
    }
	}
}

